#!/usr/bin/perl -w
#     srt2lrc  - Convert srt file to ".lrc" format
#     most codes are from sub2srt
#     http://www.robelix.com/sub2srt/

use strict;
my $version = "0.1.0";

use Getopt::Long;
Getopt::Long::Configure("pass_through","no_ignore_case");
my $help = 0;
my $fps = 25;
my $showvers = 0;
my $debug = 0;
my $quiet = 0;
my $dos = 0;
my $license = 0;
my $ntsc = 0;
my $ntsc24 = 0;
my $force = 0;
GetOptions("help|h",    \$help,
	   "version|v", \$showvers,
	   "debug|d",   \$debug,
	   "quiet|q",   \$quiet);

if ($quiet) { $debug = 0; }

if ($help) { help(); }

if ($showvers) { version(); }

my $infile = shift || '';
if (!$infile) { help(); }

my $outfile = shift || '';
if (!$outfile) {
	$outfile = $infile;
	$outfile =~ s/(\.srt|\.txt)$//i;
	$outfile .= ".lrc";
}

if (! -f $infile) {
	print "Input file $infile does not exist.\n";
	exit 0;
}

print "Input-file:  $infile\n" if ($debug);
print "Output-file: $outfile\n" if ($debug);

if (-f "$outfile" && !$force) {
	my $overwrite = "";
	while ( $overwrite ne "y" && $overwrite ne "n" ) {
		print "File \"$outfile\" already exists. Overwrite? <y|n> ";
		$overwrite = <STDIN>;
		$overwrite =~ s/\n//;
	}
	if ($overwrite ne "y") {
		exit 0;
	}
}

print "Trying to detect input format...\n" if ($debug);

my $format = detect_format($infile);
if (!$format) {
	print "Could not detect $infile format!\n";
	exit 0;
}

my $le = ($dos) ? "\r\n" : "\n";

print "Converting from $format to srt\n" if ($format ne "srt" && !$quiet);

open INFILE, "$infile" or die "Unable to open $infile for reading\n";
open OUTFILE, ">$outfile" or die "Unable to open $outfile for writing\n";

if ($format eq "srt") {
	conv_srt();
}
else {
	print "Input file is already subviewer srt format.\n";
}

close INFILE;
close OUTFILE;


#1
#00:00:00,730 --> 00:00:03,900
#15 MINUTES,15 HOURS...

sub conv_srt {
	my $converted = 0;
	my $failed = 0;
	while (my $line1 = <INFILE>) { #number
		$line1 =~ s/[\n\r]*$//;
		if ($line1 =~ m/^\d{1,4}$/) {
			$line1 = <INFILE> ; #time
	    }
		$line1 =~ s/[\n\r]*$//;
		if ($line1 =~ m/^\d\d:(\d\d:\d\d\,\d\d)\d --> \d\d:(\d\d:\d\d\,\d\d)\d$/) {
			my $starttime  = $1;
			my $endtime = $2;
			$starttime =~ s/\,/:/;
			$endtime =~ s/\,/:/;
			my $text = <INFILE>; #text
			$text =~ s/[\n\r]*$//;
			while (my $empty = <INFILE>) {
				$empty =~ s/[\n\r]*$//;
				if ($empty =~ m/^$/) {
					last;
				}
				$text = "$text $empty";
			}
			$converted++;
		
			print "  Subtitle #$converted: start: $starttime, Text: $text\n" if ($debug);
			
			# convert line-ends
			$text =~ s/\[br\]/$le/g;
			
			write_lrc($starttime, $text);
		
		} else {
			if (!$converted) {
				print "  Header line: $line1 ignored\n" if ($debug);
			} else {
				$failed++;
				print "  failed to convert: $line1\n" if ($debug);
			}
		}
	}
	print "$converted subtitles written\n" if (!$quiet);
	print "$failed lines failed\n" if (!$quiet && $failed);
}

sub write_lrc {
	my $start = shift;
	my $text = shift;
	print OUTFILE "[$start]$text$le";
}

sub detect_format {
	my $file = shift;
	open INFILE, "$file" or die "Failed to open $file.\n";
	my $detected = "";
	my $i = 0;
	while (my $line = <INFILE>) {
		$line =~ s/[\n\r]*$//;
		print "  Trying line $i: $line \n" if $debug;
		
		# microdvd format
		# looks like:
		# {startframe}{endframe}Text
		
		if ( $line =~ m/^\{\d+\}\{\d+\}.+$/ ) {
			print "  seems to be microdvd format\n" if ($debug);
			my $line2 = <INFILE>;
			$line2 =~ s/[\n\r]*$//;
			print "  checking next line: $line2\n" if ($debug);
			if ($line2 =~ m/^\{\d+\}\{\d+\}.+$/) {
				print "microdvd format detected!\n" if ($debug);
				$detected = "microdvd";
			}
		}
		
		# trying subrip format
		# 3 lines:
		# hh:mm:ss.ms,hh:mm:ss.ms
		# text
		# (empty line)
		
		if ($line =~ m/^\d\d:\d\d:\d\d\.\d\d,\d\d:\d\d:\d\d\.\d\d$/) {
			print "  seems to be subrip format\n" if ($debug);
			my $line2 = <INFILE>;
			$line2 =~ s/[\n\r]*$//;
			my $line3 = <INFILE>;
			$line3 =~ s/[\n\r]*$//;
			my $line4 = <INFILE>;
			$line4 =~ s/[\n\r]*$//;
			print "  checking the next lines:\n    $line2\n    $line3\n    $line4\n" if ($debug);
			if ($line2 =~ m/^.+$/ && $line3 =~ m/^$/ && $line4 =~ m/^\d\d:\d\d:\d\d\.\d\d,\d\d:\d\d:\d\d\.\d\d$/) {
				print "subrip format detected!\n" if ($debug);
				$detected = "subrip";
			}
		}
		
		# trying subviewer .srt format
		
		if ($line =~ m/^\d\d:\d\d:\d\d\,\d\d\d\s-->\s\d\d:\d\d:\d\d\,\d\d\d$/) {
			print "subviewer .srt format detected!\n" if ($debug);
			$detected = "srt";
		}
		
		# trying txtsub format 
		# (I called it so since it's often named .txt and I haven't found any common name for this)
		# it looks like:
		# [starttime]
		# subtitle-text
		# [endtime]
		# (the endtime can be the starttime of the next sub)
		# I've seen two variants with slightly diffrent time-formats
		# a) [00:02:05.000]
		# b) [00:02:05]
		# Both are supported
		
		if ($line =~ m/^\[\d\d:\d\d:\d\d(\.\d\d\d)?\]$/) {
			print "  seems to be txtsub format\n" if ($debug);
			my $line2 = <INFILE>;
			$line2 =~ s/[\n\r]*$//;
			my $line3 = <INFILE>;
			$line3 =~ s/[\n\r]*$//;
			print "  checking the next lines:\n    $line2\n    $line3\n" if ($debug);
			if ($line2 !~ m/\[\d\d:\d\d:\d\d(\.\d\d\d)?\]$/ && $line3 =~ m/\[\d\d:\d\d:\d\d(\.\d\d\d)?\]$/) {
				print "txtsub format detected!\n" if ($debug);
				$detected = "txtsub";
			}
		}
		
		$i++;
		last if ($detected or $i > 50);
	}
	close INFILE;
	return $detected;
}

sub help {
print <<__HELP__;

srt2lrc [options] inputfile.srt [outputfile.lrc]

    Convert subviewer ".srt" format to lrc format

Options:
    -h --help           Display this message.
    -v --version	Display Program version.
    -l --license	Display License information.

    --dos		Create output file with DOS line end (cr+lf)
			Default: unix line end (lf)

    --force		Overwrite existing files without prompt
   
    -d --debug		Print debug information
    -q --quiet		No output


inputfile.srt
    Input file
    Both types usally have the ending .srt, the format is autodetected.


[outputfile.srt]
    Output file
    Default: inputfile.lrc

__HELP__
exit 2;
}

sub license {
print <<__VERSION__;

__VERSION__
exit 2;
}

sub version {
	print "srt2lrc $version\n";
	exit 2;
}
